package view

import (
	"cloudops/src/common"
	"cloudops/src/config"
	"cloudops/src/models"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"sort"
	"strconv"
	"strings"
)

// ResponseResourceCommon 结构体表示通用的响应资源，包括总数和列表项
type ResponseResourceCommon struct {
	Total int         `json:"total"`
	Items interface{} `json:"items"`
}

// 获取所有叶子节点 做分页限制
func fetchResourceByNode(c *gin.Context) {
	sc := c.MustGet(common.GIN_CTX_CONFIG_CONFIG).(*config.ServerConfig)
	nodeId := c.DefaultQuery("nodeId", "")
	resouceType := c.DefaultQuery("resourceType", "")
	currentPage, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultQuery("pageSize", "10"))

	// 只能新增，不能去掉，因为多种资源共用的query
	searchVendor := c.DefaultQuery("Vendor", "")
	searchOSName := c.DefaultQuery("OSName", "")
	searchInstanceName := c.DefaultQuery("InstanceName", "")

	// elb 资源
	searchLoadBalancerType := c.DefaultQuery("LoadBalancerType", "")
	searchDNSName := c.DefaultQuery("DNSName", "")

	// rds 资源
	searchEngine := c.DefaultQuery("Engine", "")
	searchDBInstanceType := c.DefaultQuery("DBInstanceType", "")

	offset := 0
	limit := 0
	limit = pageSize
	if currentPage > 1 {
		offset = (currentPage - 1) * limit
	}

	if nodeId == "" || resouceType == "" {
		common.ReqBadFailWithMessage("nodeId or resouceType为空", c)
		return
	}

	// 获取当前节点下的所有叶子节点
	allNodes := []*models.StreeNode{}
	intVar, _ := strconv.Atoi(nodeId)
	dbNode, err := models.GetStreeNodeById(intVar)
	if err != nil {
		sc.Logger.Error("根据id找树节点错误", zap.Any("树节点", nodeId), zap.Error(err))
		common.FailWithMessage(err.Error(), c)
		return
	}
	if dbNode != nil {
		allNodes = append(allNodes, dbNode)
	}

	childrens := models.GetAllLeafNodes(intVar)
	allNodes = append(allNodes, childrens...)

	sc.Logger.Info("fetchResourceByNode 子节点结果打印",
		zap.Any("childrens", len(allNodes)),
		zap.Any("树节点", nodeId),
		zap.Any("Vendor", searchVendor),
		zap.Any("searchLoadBalancerType", searchLoadBalancerType),
	)

	var objs interface{}
	allResourcesIds := []int{}
	allResourcesIdsMap := map[uint]struct{}{}
	resp := &ResponseResourceCommon{}

	switch resouceType {
	case common.RESOURCE_TYPE_ECS:
		for _, node := range allNodes {
			node := node
			if node.BindEcss == nil {
				continue
			}
			for _, obj := range node.BindEcss {
				obj := obj
				// 在这里处理查询
				if searchVendor != "" && obj.Vendor != searchVendor {
					continue
				}
				if searchOSName != "" && obj.OSName != searchOSName {
					continue
				}
				allResourcesIdsMap[obj.ID] = struct{}{}
			}
		}
		for id := range allResourcesIdsMap {
			allResourcesIds = append(allResourcesIds, int(id))
		}
		if len(allResourcesIds) == 0 {
			common.OkWithDetailed(objs, "ok", c)
			return
		}

		sort.Ints(allResourcesIds)
		resp.Total = len(allResourcesIds)

		objs, err = models.GetResourceEcsByIdsWithLimitOffset(allResourcesIds, limit, offset)
		if err != nil {
			sc.Logger.Error("根据id limit offset 出错节点错误", zap.Any("树节点", nodeId), zap.Error(err))
			common.FailWithMessage(err.Error(), c)
			return
		}
		resp.Items = objs
	case common.RESOURCE_TYPE_ELB:

		for _, node := range allNodes {
			node := node
			if node.BindElbs == nil {
				continue
			}
			for _, obj := range node.BindElbs {
				obj := obj
				// 在这里处理查询
				if searchVendor != "" && obj.Vendor != searchVendor {
					continue
				}
				if searchLoadBalancerType != "" && obj.LoadBalancerType != searchLoadBalancerType {
					continue
				}

				if searchDNSName != "" && !strings.Contains(obj.DNSName, searchDNSName) {
					continue
				}

				allResourcesIdsMap[obj.ID] = struct{}{}
			}

		}
		for id := range allResourcesIdsMap {
			allResourcesIds = append(allResourcesIds, int(id))
		}
		if len(allResourcesIds) == 0 {
			common.OkWithDetailed(objs, "ok", c)
			return
		}

		sort.Ints(allResourcesIds)
		resp.Total = len(allResourcesIds)

		objs, err = models.GetResourceElbByIdsWithLimitOffset(allResourcesIds, limit, offset)
		if err != nil {
			sc.Logger.Error("根据id limit offset 出错节点错误", zap.Any("树节点", nodeId), zap.Error(err))
			common.FailWithMessage(err.Error(), c)
			return
		}
		resp.Items = objs

	case common.RESOURCE_TYPE_RDS:

		for _, node := range allNodes {
			node := node
			if node.BindRdss == nil {
				continue
			}
			for _, obj := range node.BindRdss {
				obj := obj
				// 在这里处理查询
				if searchVendor != "" && obj.Vendor != searchVendor {
					continue
				}

				if searchEngine != "" && obj.Engine != searchEngine {
					continue
				}
				if searchDBInstanceType != "" && obj.DBInstanceType != searchDBInstanceType {
					continue
				}

				if searchInstanceName != "" && !strings.Contains(obj.InstanceName, searchInstanceName) {
					continue
				}

				allResourcesIdsMap[obj.ID] = struct{}{}
			}

		}
		for id := range allResourcesIdsMap {
			allResourcesIds = append(allResourcesIds, int(id))
		}
		if len(allResourcesIds) == 0 {
			common.OkWithDetailed(objs, "ok", c)
			return
		}

		sort.Ints(allResourcesIds)
		resp.Total = len(allResourcesIds)

		objs, err = models.GetResourceRdsByIdsWithLimitOffset(allResourcesIds, limit, offset)
		if err != nil {
			sc.Logger.Error("根据id limit offset 出错节点错误", zap.Any("树节点", nodeId), zap.Error(err))
			common.FailWithMessage(err.Error(), c)
			return
		}
		resp.Items = objs

	}
	common.OkWithDetailed(resp, "ok", c)
}
